package com.demo.unittest.mapreduce;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

/**
 * !!!一个错误的对于context的mock
 * 由于mapper重用text对象的特性, 这里verify会失效.
 *
 * @author tzp
 * @since 2018/5/16
 */
@RunWith(MockitoJUnitRunner.class)
public class TokenizerMapperTestWrong {

    private final static IntWritable one = new IntWritable(1);
    private TokenizerMapper mapper = new TokenizerMapper();
    private Text line = new Text();
    private Text word = new Text();
    @Mock
    private Mapper.Context context;

    @Test
    public void testMapper() throws Exception {
        //arrange
        line.set("foo bar foo");

        //act
        mapper.map(null, line, context);

        //assert
        word.set("foo");
        verify(context, times(2)).write(word, one); //3

        //!!!一种易碎的断言. 取决于mapper逻辑, 如果mapper不是write foo三次one, 而是write了一次three, 这里就错了
        //!!!一个错误的对于context的mock, 由于mapper重用text对象的特性, 这里verify会失效. 不要mock你不能掌控的东西
    }

}